import { App } from "../../../../src/App";
import { Matrix } from "../../../../src/core/Class";
import Map from "../../../../src/core/Map";
import { PokerData, PokerType, PokerWeight, Union } from "../../../src/BaseLogic";
import { UserData } from "../../../src/BaseModule";
import GameLogic from "../Game/GameLogic";
import { CallScore, CreateLandlord, Deal, Discard, GameModule, LandlordEvents, Settlement } from "../Game/GameModule";

export default class Robot extends Matrix {
    private _userInfo:UserData = null;
    private _seatIdx:number = -1; // 座位ID
    private _landload:number = -1;
    private _discardInfo:Map<number,PokerData[]> = new Map<number,PokerData[]>();
    private _hands:PokerData[] = [];
    

    public get info():UserData{return this._userInfo;}

    protected onInit(userInfo:UserData,seatIdx:number){
        this._userInfo = userInfo;
        this._seatIdx = seatIdx;

        // 自动入桌后并准备
        cc.tween(this).delay(2*this._seatIdx)
        .call(()=>{
            App.Event.emit(LandlordEvents.EC_ENTRY_ROOM,{seat:this._seatIdx,user:this._userInfo});
        }).delay(2)
        .call(()=>{ 
            this._clean();
            App.Event.emit(LandlordEvents.EC_READY,{seat:this._seatIdx,next:-1});
         }).start();

         // 发牌
         App.Event.on(LandlordEvents.EC_GAME_RESSET,()=>{
            this._clean();
            setTimeout(() => {
                App.Event.emit(LandlordEvents.EC_READY,{seat:this._seatIdx,next:-1});
            }, this._seatIdx*1000);
         },this);

        // 发牌
        App.Event.on(LandlordEvents.EC_DEAL,(data:Deal)=>{
            data.info.forEach((it)=>{
                if (it.seat === this._seatIdx){
                    console.log(`Robot.deal:${this._seatIdx}=${JSON.stringify(data.info[this._seatIdx].cards)}`);
                    this._hands = GameLogic.sort(it.cards);
                    return ;
                }
            });
        },this);
        
        App.Event.on(LandlordEvents.EC_NOTICE_CALL,(data:CallScore)=>{
            if (data.next === this._seatIdx){
                console.log(`Robot.noticeCall:${this._seatIdx}=${JSON.stringify(data)}`);
                const pkg:CallScore = {
                    seat:this._seatIdx,
                    next:-1,
                    score:GameLogic.appraise(this._hands),
                }
                App.Event.emit(LandlordEvents.EC_CALL,pkg);
            }
        },this);

        // 游戏开始，是否是地主
        App.Event.on(LandlordEvents.EC_BUILD_BANKER,(data:CreateLandlord)=>{
            this._landload = data.seat;
            if (data.seat === this._seatIdx){
                console.log(`Robot.landlord:${this._seatIdx}=${JSON.stringify(data)}`);
                this._hands = GameLogic.sort(App.Util.concatArray(this._hands,data.cards));
                setTimeout(() => {
                    this._discard();
                }, this._seatIdx*2000);
            }
        },this);

        App.Event.on(LandlordEvents.EC_NOTICE_DISCARD,(data:Discard)=>{
            this._discardInfo.inset(data.seat,data.cards);
            if (data.seat === this._seatIdx){
                data.cards.forEach((card:PokerData)=>{
                    const index = this._hands.indexOf(card);
                    index > -1 && this._hands.splice(index,1);
                });
            }

            // 下家是自己延迟出牌
            if (data.next === this._seatIdx){
                setTimeout(() => {
                    this._discard();
                }, data.delayTime*1000);
            }
        },this);

        App.Event.on(LandlordEvents.EC_GAME_OVER,(data:Settlement)=>{
            for (let it of data.info){
                if (it.seat === this._seatIdx){
                    this._userInfo.Coin += it.score;
                    break ;
                }
            }
            this._clean();
        },this);
    }

    protected onDestroy(){
        App.Event.offAll(this);
    }

    private _discard(){
        const last = GameModule.getLast(this._seatIdx,this._discardInfo);
        let info:Union = {cards:[],type:PokerType.unknow,weight:PokerWeight.unknow,min:-1};
        const canUnion:Union[] = GameLogic.findCanDiscard(this._hands,last.seat === this._seatIdx?[]:last.cards);
        const next = GameModule.getNext(this._seatIdx);
        if (!canUnion){
            info.cards = [];
        } else {
            if (last.seat !== this._seatIdx){
                // 压牌，目的是不让下家或者再下一家出牌,所以取最大牌出，可能会是飞机、王炸和炸弹中的一种
                info.cards = (this._isLandload || this._landload === next) ? canUnion.pop().cards : canUnion.shift().cards;
            } else info.cards = canUnion.shift().cards;

            !GameLogic.isValid(info.cards,last.cards) && (info.cards = []);
        }
        const pkg:Discard = {
            cards:info.cards,
            seat:this._seatIdx,
            next:-1,
            delayTime:-1,
        };
        App.Event.emit(LandlordEvents.EC_DISCARD,pkg);
    }

    private _clean(){
        this._discardInfo.clear();
        this._landload = -1;
        this._hands = [];
    }


    private get _isLandload():boolean {return this._landload === this._seatIdx}
}
